<template>
  <div id="mountNode">
    <div class="mask-container" v-if="isMask"></div>
    <div :class="['editor', isFullScreen ? 'fullScreen' : '']">
      <toolbar
        v-show="isShowToolbar"
        :toolbarConf="toolbarConf"
        :compBoxInfo="GT_compBoxInfo"
      ></toolbar>
      <div class="bottom-container">
        <o-card-box
          :isExpand="isExpand"
          position="left"
          :width="itemPanelWidth"
        >
          <item-panel
            :list="G_itemList"
            :compBoxInfo="GT_compBoxInfo"
            v-show="!hideItemPanel"
          />
        </o-card-box>
        <!-- 在此放入任意vue组件 -->
        <slot name="comp" />

        <minimap :isShow="showMap" :compBoxInfo="GT_compBoxInfo" />
        <page
          :autoSize="autoSize"
          :height="height"
          :width="width"
          :data="graphData"
          :fitView="fitView"
          :nodeContextMenuConf="nodeContextMenuConf"
          :compBoxInfo="GT_compBoxInfo"
        />
        <slot name="openData" />
      </div>

      <div></div>
    </div>
  </div>
</template>

<script lang="ts">
import {
  T_srv,
  Tsrv,
  ts,
  ifs,
  T_editor,
  I_editor,
  toolbar,
  ItemPanel,
  minimap,
  page,
  T_graphToolbar,
  I_graphToolbar,
  vue,
  N_oFlowchart
} from './config';
import { N_oSimpleToolbar } from './editToolbar/config';

@T_srv.comp({
  components: {
    toolbar,
    ItemPanel,
    minimap,
    page
  }
})
export default class oFlowchart extends vue {
  // 父组件compBoxInfo
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  @T_srv.prop({ required: false, default: 0 }) height: number;

  @T_srv.prop({ required: false, default: 0 }) width: number;

  @T_srv.prop({ required: false, default: false }) autoSize: boolean;

  @T_srv.prop({ required: false, default: () => {} }) graphData: object;

  @T_srv.prop({ required: false, default: () => {} })
  nodeContextMenuConf: N_oFlowchart.I_contextMenuConf;

  @T_srv.prop({ required: false, default: true }) fitView: boolean;

  @T_srv.prop({ type: Array, required: false, default: [] }) itemList: Array<
    object
  >;

  @T_srv.prop({ type: Array, required: false, default: () => [] })
  toolbarConf: Array<N_oSimpleToolbar.I_Conf>;

  private GT_editor: I_editor;

  private G_modalList: Array<any> = [];

  // modal编号
  private G_modalIdx: number = 0;

  private GT_graphToolbar: I_graphToolbar;

  public GT_compBox: ifs.I_compBox = null;

  private G_compID: string;

  public isMask: boolean = false;

  public GT_compBoxInfo: ifs.I_compBoxInfo;

  public G_itemList: Array<object> = [];

  public hideItemPanel: boolean = false;

  public isExpand: boolean = false;

  public itemPanelWidth: number = 120;

  public showMap: boolean = false;

  private timerID;

  private isShowToolbar = true;

  private isFullScreen: boolean = false;

  created() {
    this.G_compID = Tsrv.utils.getGUID();
    // 如果外部有传入组件信息
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox = new ts.T_compBox(this.G_compID); // 使用本地实例
    } else {
      this.G_compID = this.compBoxInfo.compID;
      this.GT_compBox = this.compBoxInfo.TcompBox;
    }
    this.GT_compBoxInfo = { compID: this.G_compID, TcompBox: this.GT_compBox };
    this.GT_compBox.addCompMergeName(this.G_compID, 'oFlowchart', this);

    this.GT_editor = new T_editor(this.GT_compBoxInfo);
    this.GT_compBox.addCompMergeName(this.G_compID, `editor`, this.GT_editor);
    this.GT_graphToolbar = new T_graphToolbar(this.GT_compBoxInfo);

    this.GT_compBox.addCompMergeName(
      this.G_compID,
      `graphToolbar`,
      this.GT_graphToolbar
    );
    this.G_itemList = Tsrv.utils.clone(this.itemList, true);
  }

  destroyed() {
    // 退出时销毁
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        'oFlowchart',
        'editor',
        'graphToolbar'
      ]);
    }
    this.GT_editor = null;
    this.GT_graphToolbar = null;
    this.GT_compBox = null;
  }

  mounted() {
    this.init();

    this.$emit('compBoxInfo', this.GT_compBoxInfo); // 将compID 告之父组件本组件ID
  }

  getCompBox(): ts.T_compBox {
    return this.GT_compBox;
  }

  getCompID(): string {
    return this.G_compID;
  }

  regGraphToolBarFn(obj: N_oFlowchart.I_regFn) {
    this.GT_editor.regFn(obj);
  }

  private init() {
    // 阻止浏览器默认右键菜单
    // eslint-disable-next-line func-names
    document.oncontextmenu = function(event) {
      if (event.stopPropagation) {
        event.stopPropagation();
      }
      if (event.preventDefault) {
        event.preventDefault();
      }
    };
  }

  /**
   * description: 设置边hover状态
   */

  setEdgehoverStyles(edgeID: string, isShow: boolean) {
    this.GT_editor.setEdgehoverStyles(edgeID, isShow);
  }

  onNodeSelect(e) {
    this.$emit(`on-node-select`, e);
  }

  onCanvasClick(e) {
    this.$emit(`on-canvas-click`, e);
  }

  onEdgeSelect(e) {
    this.$emit('on-edge-select', e);
  }

  onOpenDataRow(row: any) {
    this.$emit(`on-open-data-row`, row);
  }

  onNodeRightClick(e) {
    this.$emit('on-node-right-click', {
      state: this.GT_editor.editorState,
      e
    });
  }

  onGraphEditorState(e) {
    this.$emit(`on-graph-editor-state`, e);
  }
  // 统一在onGraphToolBarClick中处理
  // onGraphOpenData(callback) {
  //   this.$emit(`on-graph-open-data`, callback);
  // }

  // 工具档点击事件
  onGraphToolbarClick(p: N_oFlowchart.I_toolbarClick) {
    switch (p.key) {
      case 'fullScreen':
        // this.isFullScreen = !this.isFullScreen;
        this.isFullScreen = !this.isFullScreen; // 需优化
        // 1、调用 screenChange 方法 切换 ‘全屏’‘还原’ 按钮
        this.GT_compBox.getCompMergeName(
          this.G_compID,
          `editToolbar`
        ).screenChange();

        // 2、调用 osimpletoolbar的 calculateVisibleButtons方法 此方法重新计算 toolbar的样式
        this.GT_compBox.getCompMergeName(
          this.G_compID,
          `oSimpleToolbar`
        ).recalculate();
        break;
      default:
        this.$emit(`on-graph-toolbar-click`, p);
    }
    // this.$emit(`on-graph-toolbar-click`, p);
  }

  setToolbarBtnsDisabled(btnName: string, s: boolean) {
    this.GT_compBox.getCompMergeName(
      this.G_compID,
      `graphToolbar`
    ).setBtnDisabled(btnName, s);
  }

  regFns(fns: Array<N_oFlowchart.I_regFn>): void {
    if (fns.length > 0) {
      this.GT_editor.regFns(fns);
    }
  }

  loadGraphData(d: any, isFitView: boolean = false) {
    this.GT_editor.loadData(d, isFitView);
  }

  clearGraph() {
    this.initGraph();
  }

  // 隐藏工具栏按扭
  hideToolbarItem(name: string) {
    this.GT_compBox.getCompMergeName(
      this.G_compID,
      'editToolbar'
    ).hideToolbarItem(name);
  }

  // 隐藏工具栏
  hideToolbar() {
    this.isShowToolbar = false;
  }

  // 显示工具栏
  showToolbar() {
    this.isShowToolbar = true;
  }

  initGraph() {
    this.GT_editor.initGraph();
  }

  setViewMode() {
    this.GT_graphToolbar.saveMode();
  }

  onAfterRender(e) {
    // 只取最后一次
    clearTimeout(this.timerID);
    this.timerID = setTimeout(() => {
      this.$emit('on-after-render', { state: this.GT_editor?.editorState, e });
    }, 50);
  }

  // 实际尺寸
  resetZoom() {
    this.GT_graphToolbar.btnResetZoom();
  }

  // 自动大小
  autoZoom() {
    this.GT_graphToolbar.btnAutoZoom();
  }

  setToolbarViewMode() {
    this.GT_graphToolbar.setToolbarViewMode();
  }

  setToolbarEditMode() {
    this.GT_graphToolbar.setEditMode();
  }
}
</script>

<style scoped lang="scss">
.bottom-container {
  position: relative;
  // top: 43px;
  width: 100%;
  height: calc(100% - 43px);
}

#mountNode,
.editor {
  height: 100%;
  width: 100%;
  padding: 0;
  margin: 0;
  position: relative;
  &.fullScreen {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 9999;
    background-color: #fff;
  }
}

.toolbar {
  padding: 0;
  overflow: auto;
}
::v-deep .g6-component-toolbar {
  position: unset;
  display: none;
}
</style>
